#!/usr/bin/env bash
# Copyright (c) 2021 maminjie <canpool@163.com>
# SPDX-License-Identifier: MulanPSL-2.0

method_def git


usage_git() {
    module_usage "git" "git command-line tool"
}

do_git() {
    module_do "git" "$@"
}

git_usage_help() {
    module_usage_help git
}

# git_do_help subcmd
git_do_help() {
    module_do_help git "$1"
}

# __git_get_subcmd cmd
#   Get the fullname of cmd
# Returns:
#   "" or fullname
__git_get_subcmd() {
    local cmd=""
    case "${1}" in
        "h"|"help")
            cmd="help"
            ;;
        "le"|"loge"|"logexp")
            cmd="logexp"
            ;;
        "as"|"alias")
            cmd="alias"
            ;;
        "k"|"key")
            cmd="key"
            ;;
        "cl"|"clone")
            cmd="clone"
            ;;
        *)
            ;;
    esac
    echo "$cmd"
}

git_curbranch() {
    git symbolic-ref --short -q HEAD
}

# git_check_localrepo
#   Check whether the current directory is a git repo
# Returns:
#   0 - yes
#   !0 - no
git_check_localrepo() {
    git rev-parse --is-inside-work-tree &>/dev/null
}

# git_msg [COMMIT_ID]
git_msg() {
    git log -1 --pretty=format:"%s%n%n%b" $@
}

# git_check_localbranch branch
#   Check whether the branch is in the local git repo
# Returns:
#   0 - yes
#   !0 - no
git_check_localbranch() {
    if [ $# -ne 1 ]; then
        return 1
    fi
    local branch="$(git branch -l $1)"
    if [ -z "$branch" ]; then
        return 1
    fi
    return 0
}

git_getpasswd() {
    local passwd=$(setting_get gitee passwd)
    if [ -z "$passwd" ]; then
        stty -echo
        read -r -p "Password for gitee: " passwd
        stty echo
    fi
    echo "$passwd"
}

git_usage_logexp() {
printf "logexp (loge, le): Export git logs (csv format)

Usage:
    ${PROG} git loge [<revision-range>] [ver]

Examples:
    ${PROG} git le                      # export all logs
    ${PROG} git le start..end [ver]     # export logs between (start, end]
\n"
}

# git_do_logexp [<revision-range>]
git_do_logexp() {
    git_check_localrepo
    if [ $? -ne 0 ]; then
        git_usage_logexp; exit
    fi
    local version=""
    if [ $# -ge 2 ]; then
        version=$2
    fi
    local commit_ids=$(git log --no-merges --pretty=format:"%H" $1)
    [[ -n "$version" ]] && echo -n "version,"
    echo "commit id,summary,brief,stat,datetime,insertion(+),deletion(-)"
    for id in $commit_ids; do
        local summary=$(git log $id -n1 --pretty=format:"%s" | sed 's/"/""/g')
        local brief=$(git log $id -n1 --pretty=format:"%b" | sed 's/"/""/g')
        local stat=$(git show $id --stat --oneline | sed '1d')
        local changes=$(echo "$stat" | grep -E "file[s]? changed")
        stat=$(echo "$stat" | head -n100)
        local insertion=$(echo "$changes" | awk '{print $4}')
        [[ -z "$insertion" ]] && insertion=0
        local deletion=$(echo "$changes" | awk '{print $6}')
        [[ -z "$deletion" ]] && deletion=0
        local datetime=$(git log $id -n1 --pretty=format:"%cd" --date=format:'%Y-%m-%d %H:%M:%S')
        [[ -n "$version" ]] && echo -n "$version,"
        echo "$id,\"$summary\",\"$brief\",\"$stat\",\"$datetime\",$insertion,$deletion"
    done
}

git_usage_alias() {
printf "alias (as): config some global alias

usage:
    ${PROG} git alias
\n"
}

git_do_alias() {
    git config --global alias.co checkout
    git config --global alias.br branch
    git config --global alias.ci commit
    git config --global alias.st status
    git config --global alias.rt remote
    git config --global alias.lo 'log --oneline --topo-order'
    git config --global alias.unstage 'reset HEAD'
    git config --global alias.lp 'log -p --topo-order'
    git config --global alias.last 'log -1 HEAD --topo-order'
    git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
    git config --global alias.ak 'am --keep-non-patch'
    git config --global alias.ar 'apply --reject'
    git config --global -l
}

git_usage_key() {
printf "key (k): Generate ssh key

usage:
    ${PROG} git key EMAIL

process:
    ssh-keygen -t rsa -C EMAIL
\n"
}

# git_do_key EMAIL
git_do_key() {
    if [ $# -ne 1 ]; then
        git_usage_key; exit
    fi
    ssh-keygen -t rsa -C "$1"
}

git_usage_clone() {
printf "clone (cl): clone git repo from remote

usage:
    ${PROG} git clone [<options>] [--] <repo> [<dir>]
\n"
}

# git_do_clone ...
git_do_clone() {
    if [ $# -lt 1 ]; then
        git_usage_clone; exit
    fi
    while true; do
        git clone $@
        [[ $? -eq 0 ]] && break
    done
}

git_docheck() {
    check_command "git"
    check_command "expect"
    check_command "ssh-keygen"
}
